﻿using System.Linq;
using CID.Domain.Users;
using CID.Tests.Support;
using NUnit.Framework;

namespace CID.Domain.Persistence.Tests.Users
{
    [TestFixture]
    class UserPersistenceTests : BasePersistenceWithDataTests
    {
        private static void AssertAreEqual(User expected, User actual)
        {
            Assert.AreEqual(expected.Id, actual.Id);
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.UserName, actual.UserName);
            Assert.AreEqual(expected.Email, actual.Email);
            Assert.AreEqual(expected.Enabled, actual.Enabled);
            CollectionAssert.AreEquivalent(expected.AssignedRoles.Select(x => x.UserRole), actual.AssignedRoles.Select(x => x.UserRole));
        }

        [Test]
        public void PersistNewUser_UserShouldBeSaved()
        {
            var session = OpenSession();
            var newUser = DataProvider.CreateUser(userRoles: new UserRole[] { UserRole.Architect, UserRole.ComponentManager });
            session.SaveOrUpdate(newUser);
            CleanSession(session);

            Assert.AreNotEqual(NotSavedId, newUser.Id);
            session = OpenSession();
            var retrievedUser = session.Get<User>(newUser.Id);
            Assert.IsNotNull(retrievedUser);
            AssertAreEqual(newUser, retrievedUser);
            CleanSession(session);
        }

        [Test]
        public void PersistModifiedUser_ChangesShouldBeSaved()
        {
            var session = OpenSession();
            var user = DataProvider.CreateUser(userRoles: new UserRole[] { UserRole.Architect, UserRole.ComponentManager });
            session.SaveOrUpdate(user);
            CleanSession(session);

            session = OpenSession();
            var modifiedUser = session.Get<User>(user.Id);
            modifiedUser.AssignRole(UserRole.Developer);
            modifiedUser.UnassignRole(UserRole.Architect);
            modifiedUser.ModifyProperty(x => x.Name);
            modifiedUser.ModifyProperty(x => x.UserName);
            modifiedUser.ModifyProperty(x => x.Email);
            modifiedUser.Enabled = false;
            CleanSession(session);

            session = OpenSession();
            var retrievedUser = session.Get<User>(user.Id);
            AssertAreEqual(modifiedUser, retrievedUser);
            CleanSession(session);
        }

        [Test]
        public void DeleteUser_UserShouldBeDeleted()
        {
            var session = OpenSession();
            var user1 = DataProvider.CreateUser();
            var user2 = DataProvider.CreateUser();
            session.SaveOrUpdate(user1);
            session.SaveOrUpdate(user2);
            CleanSession(session);

            session = OpenSession();
            var retrievedUser1 = session.Get<User>(user1.Id);
            var retrievedUser2 = session.Get<User>(user2.Id);
            session.Delete(retrievedUser1);
            CleanSession(session);

            session = OpenSession();
            retrievedUser1 = session.Get<User>(user1.Id);
            retrievedUser2 = session.Get<User>(user2.Id);
            Assert.IsNull(retrievedUser1);
            Assert.IsNotNull(retrievedUser2);
            CleanSession(session);
        }
    }
}
